package cn.sdormitory.component.aspect;


import cn.sdormitory.basedata.dao.BClassDao;
import cn.sdormitory.basedata.dao.BDormitoryDao;
import cn.sdormitory.basedata.dao.BStudentDao;
import cn.sdormitory.basedata.entity.BClass;
import cn.sdormitory.basedata.entity.BDormitory;
import cn.sdormitory.basedata.entity.BStudent;
import cn.sdormitory.common.sms.TxSmsTemplate;
import cn.sdormitory.common.utils.SysUserUtils;
import cn.sdormitory.smartdor.dao.SdAttenceDao;
import cn.sdormitory.smartdor.dao.SdAttenceTrackRecordDao;
import cn.sdormitory.smartdor.entity.SdAttence;
import cn.sdormitory.smartdor.entity.SdAttenceTrackRecord;
import cn.sdormitory.sys.dao.SysDeptDao;
import cn.sdormitory.sys.dao.SysDictDetailDao;
import cn.sdormitory.sys.dao.SysUserDao;
import cn.sdormitory.sys.entity.SysDept;
import cn.sdormitory.sys.entity.SysDictDetail;
import cn.sdormitory.sys.entity.SysUser;
import cn.sdormitory.workflow.dao.NotRetrunedApplyDao;
import cn.sdormitory.workflow.service.HygieneRectificationApplyService;
import cn.sdormitory.workflow.service.ViolationApplyService;
import cn.sdormitory.workflow.vo.NotRetrunedApplyVO;
import cn.sdormitory.workflow.vo.WorkFlowVO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * 流程处理时找到审批人
 */
@Aspect
@Component
@Slf4j
public class ActivityAssigneeAspect {

    @Resource
    NotRetrunedApplyDao notRetrunedApplyDao;
    @Resource
    SysDeptDao SysDeptDao;
    @Resource
    BClassDao bClassDao;
    @Resource
    SysUserDao sysUserDao;
    @Resource
    SdAttenceDao sdAttenceDao;
    @Resource
    BStudentDao bStudentDao;
    @Resource
    private TxSmsTemplate txSmsTemplate;
    @Resource
    private SdAttenceTrackRecordDao sdAttenceTrackRecordDao;
    @Resource
    ViolationApplyService violationApplyService;

    @Autowired
    HygieneRectificationApplyService rectificationApplyService;

    @Before("execution(* cn.sdormitory.workflow.service.impl.WorkFlowCommonServiceImpl.processWorkFlow(..))")
    public void assigneeBefore(JoinPoint point) {
        WorkFlowVO vo = (WorkFlowVO)point.getArgs()[0];
        log.info("before-args : {}",JSON.toJSONString(vo));

        if(vo.getApplyID().startsWith("notRetrunApplyNew")){
            LambdaQueryWrapper<NotRetrunedApplyVO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(NotRetrunedApplyVO::getProcessInstanceId, vo.getProcessInstanceId());
            NotRetrunedApplyVO notRetrunedApplyVO = notRetrunedApplyDao.selectOne(wrapper);
            //设置流程审批人
            setNotRetrunApplyApprover(vo, notRetrunedApplyVO);
        }
        if(vo.getApplyID().startsWith("sdViolationFlow")){
            //设置宿舍违纪流程审批人
            violationApplyService.setApprover(vo);
        }
        if(vo.getApplyID().startsWith("HygieneRectificationApply")){
            //设置卫生审批人
            rectificationApplyService.setApprover(vo);
        }
    }

    /**
     * 设置流程审批人
     * @param vo
     * @param notRetrunedApplyVO
     */
    private void setNotRetrunApplyApprover(WorkFlowVO vo, NotRetrunedApplyVO notRetrunedApplyVO) {
        Map<String, Object> map = new HashMap<>();
        SysDept sysdept = deptInfo("宿管中心");
        String smsContext = "";
        if(vo.getCurrNode().startsWith("classTeacherHandle")){
            if(0 == vo.getFlag()){ //提交到部门经理
                smsContext = "无法联系学生，提交到部门经理处理";
                String username = teacherId(notRetrunedApplyVO.getClassId());
                String assignee = getDeptManager(username).getLeader();
                map.put("assignee",assignee);
                vo.setVariables(map);
                //发送短信通知
                sendSMS(assignee,notRetrunedApplyVO,smsContext);
                sendSMS(sysdept.getLeader(),notRetrunedApplyVO,smsContext);
                saveHistory(smsContext,"5",notRetrunedApplyVO,SysUserUtils.getSysUser().getUsername());
            }
            if(1 == vo.getFlag()){//学生在宿舍，提交到宿管处理
                smsContext = "学生在宿舍";
                String assignee = notRetrunedApplyVO.getCreateBy();
                map.put("assignee", assignee);
                vo.setVariables(map);
                //发送短信通知
                sendSMS(assignee,notRetrunedApplyVO,smsContext);
                sendSMS(sysdept.getLeader(),notRetrunedApplyVO,smsContext);
                saveHistory(smsContext,"4",notRetrunedApplyVO, SysUserUtils.getSysUser().getUsername());
            }
            if(2 == vo.getFlag()){//老师忘记提交学生请假申请
                smsContext = "忘记提交请假";
                //发送短信通知
                sendSMS(notRetrunedApplyVO.getCreateBy(),notRetrunedApplyVO,smsContext);
                sendSMS(sysdept.getLeader(),notRetrunedApplyVO,smsContext);
                saveHistory(smsContext,"4",notRetrunedApplyVO,SysUserUtils.getSysUser().getUsername());
            }
            if(3 == vo.getFlag()){//学生未请假私自离校
                smsContext = "学生未请假私自离校";
                //发送短信通知
                sendSMS(notRetrunedApplyVO.getCreateBy(),notRetrunedApplyVO,smsContext);
                sendSMS(sysdept.getLeader(),notRetrunedApplyVO,smsContext);
                saveHistory(smsContext,"4",notRetrunedApplyVO,SysUserUtils.getSysUser().getUsername());
            }
        }
        //部门经理处理
        if(vo.getCurrNode().startsWith("deptManageHandle")){
            smsContext = "部门经理已处理"+"["+vo.getApplyDesc()+"]";
            sendSMS(notRetrunedApplyVO.getCreateBy(),notRetrunedApplyVO,smsContext);
            saveHistory(vo.getApplyDesc(),"6",notRetrunedApplyVO,SysUserUtils.getSysUser().getUsername());
            sendSMS(sysdept.getLeader(),notRetrunedApplyVO,smsContext);
        }
        //宿管处理
        if(vo.getCurrNode().startsWith("presenterHandle")){
//            if(0 == vo.getFlag()){//驳回给班主任
//                smsContext = "宿管确认学生未归寝";
//                String assignee = teacherId(notRetrunedApplyVO.getClassId());
//                map.put("assignee",assignee);
//                vo.setVariables(map);
//                //发送短信通知
//                sendSMS(assignee,notRetrunedApplyVO,smsContext);
//                saveHistory(smsContext,"8",notRetrunedApplyVO,SysUserUtils.getSysUser().getUsername());
//                sendSMS(sysdept.getLeader(),notRetrunedApplyVO,smsContext);
//            }
            if(1 == vo.getFlag()) {
                smsContext = "宿管已确认学生已归寝状态，处理结束";
                saveHistory(smsContext,"7",notRetrunedApplyVO,SysUserUtils.getSysUser().getUsername());
                sendSMS(sysdept.getLeader(),notRetrunedApplyVO,smsContext);
            }
        }
    }

    @Resource
    BDormitoryDao bDormitoryDao;
    @Resource
    SysDictDetailDao sysDictDetailDao;
    private void sendSMS(String assignee,NotRetrunedApplyVO notRetrunedApplyVO,String statusVal) {
        //查询宿舍信息
        BDormitory bDormitory = bDormitoryDao.selectById(notRetrunedApplyVO.getSdId());
        LambdaQueryWrapper<SysDictDetail> dictDetailWrapper = new LambdaQueryWrapper<>();
        dictDetailWrapper.eq(SysDictDetail::getDictType,"sys_building");
        dictDetailWrapper.eq(SysDictDetail::getDictValue,bDormitory.getBuildingNo());
        SysDictDetail sysDictDetail = sysDictDetailDao.selectOne(dictDetailWrapper);

        if(assignee!=null){
            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUser::getUsername,assignee);
            SysUser sysUser = sysUserDao.selectOne(wrapper);
            String [] content ={sysDictDetail.getDictLabel()+"-"+bDormitory.getDormitoryNo(),notRetrunedApplyVO.getStudentName(),statusVal};
            txSmsTemplate.sendMesModel(sysUser.getPhone(),content,7);
        }


    }

    private void saveHistory(String statusVal, String type,NotRetrunedApplyVO notRetrunedApplyVO,String createBy) {
        BDormitory bDormitory = bDormitoryDao.selectById(notRetrunedApplyVO.getSdId());
        SdAttenceTrackRecord SdAttenceTrackRecord = new SdAttenceTrackRecord();
        SdAttenceTrackRecord.setBdormitoryId(bDormitory.getId());
        SdAttenceTrackRecord.setBuildingNo(bDormitory.getBuildingNo());
        SdAttenceTrackRecord.setStorey(bDormitory.getStorey());
        SdAttenceTrackRecord.setDormitoryNo(bDormitory.getDormitoryNo());
        SdAttenceTrackRecord.setType(type);
        SdAttenceTrackRecord.setResult(statusVal);
        SdAttenceTrackRecord.setStudentId(Long.valueOf(notRetrunedApplyVO.getStudentId()));
        SdAttenceTrackRecord.setContactDate(notRetrunedApplyVO.getNotRetrunedDate());
        SdAttenceTrackRecord.setCreateBy(createBy);
        sdAttenceTrackRecordDao.insert(SdAttenceTrackRecord);
    }


    @AfterReturning(returning="desReturnValue",pointcut="execution(* cn.sdormitory.workflow.service.impl.WorkFlowCommonServiceImpl.processWorkFlow(..))")
    public void processAfterReturning(Object desReturnValue) {
        //打印返回值对象
//        System.out.println(String.valueOf(desReturnValue));
        log.info("after-return : {}",JSON.toJSONString(desReturnValue));
        WorkFlowVO vo = (WorkFlowVO)desReturnValue;
        //未归寝处理流程
        if(vo.getApplyID().startsWith("notRetrunApplyNew")){
            notReturnedProcess(vo);
        }
        if(vo.getApplyID().startsWith("sdViolationFlow")){
            //宿舍违纪流程处理
            violationApplyService.processResult(vo);
        }
        if(vo.getApplyID().startsWith("HygieneRectificationApply")){
            //卫生
            rectificationApplyService.processResult(vo);
        }

    }

    /**
     * 查询班主任
     * @param classId
     * @return
     */
    private String teacherId(String classId){
        BClass bClass = bClassDao.selectById(classId);
        Long approve = bClass.getClassTeacherId();
        SysUser sysUser = sysUserDao.selectById(approve);
        return sysUser.getUsername();
    }
    /**
     * 查询部门信息
     * @return
     */
    private SysDept deptInfo(String deptName){
        LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDept::getName,deptName);
        SysDept sysDept = this.SysDeptDao.selectOne(wrapper);
        return sysDept;
    }

    /**
     * 查询部门经理审批人
     * @return
     */
    private SysDept getDeptManager(String userName){
        LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(SysUser::getUsername,userName);
        SysUser sysUser = sysUserDao.selectOne(userWrapper);

        LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDept::getId,sysUser.getDeptId());
        SysDept sysDept = this.SysDeptDao.selectOne(wrapper);
        return sysDept;
    }

    private void notReturnedProcess(WorkFlowVO vo) {
        NotRetrunedApplyVO applyVO = new NotRetrunedApplyVO();
        LambdaQueryWrapper<NotRetrunedApplyVO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NotRetrunedApplyVO::getProcessInstanceId, vo.getProcessInstanceId());
        NotRetrunedApplyVO notRetrunedApplyVO = notRetrunedApplyDao.selectOne(wrapper);
        if(vo.getCurrNode().startsWith("classTeacherHandle")){
            if(2 == vo.getFlag()){
                //老师忘记提交学生请假申请
                applyVO.setApplyStatus("3");
                notRetrunedApplyDao.update(applyVO,wrapper);
                BStudent student = bStudentDao.getStudentById(Integer.valueOf(notRetrunedApplyVO.getStudentId()));
                sdAttenceDao.updateAttenceStatus(student.getStudentNo(),notRetrunedApplyVO.getNotRetrunedDate(),"4");
            }
            if(3 == vo.getFlag()){ //学生未请假离校
                BStudent student = bStudentDao.getStudentById(Integer.valueOf(notRetrunedApplyVO.getStudentId()));
                sdAttenceDao.updateAttenceStatus(student.getStudentNo(),notRetrunedApplyVO.getNotRetrunedDate(),"6");
                applyVO.setApplyStatus("10");
                applyVO.setModifyTime(new Date());
                notRetrunedApplyDao.update(applyVO,wrapper);
            }
        }
        //部门经理处理
        if(vo.getCurrNode().startsWith("deptManageHandle")){
            if(1== vo.getFlag()){
                BStudent student = bStudentDao.getStudentById(Integer.valueOf(notRetrunedApplyVO.getStudentId()));
                sdAttenceDao.updateAttenceStatus(student.getStudentNo(),notRetrunedApplyVO.getNotRetrunedDate(),"6");
                applyVO.setApplyStatus("10");
                notRetrunedApplyDao.update(applyVO,wrapper);
            }

        }
        if(vo.getCurrNode().startsWith("presenterHandle")){
//            if(0== vo.getFlag()){
//                applyVO.setApplyStatus("1");
//                notRetrunedApplyDao.update(applyVO,wrapper);
//            }
            if(1== vo.getFlag()){//审批通过
                applyVO.setApplyStatus("10");
                applyVO.setViolationPhoto(vo.getAttachment());
                applyVO.setModifyTime(new Date());
                notRetrunedApplyDao.update(applyVO,wrapper);
                //学生在宿舍，考勤状态为违纪（在寝确认）
                BStudent student = bStudentDao.getStudentById(Integer.valueOf(notRetrunedApplyVO.getStudentId()));
                sdAttenceDao.updateAttenceStatus(student.getStudentNo(),notRetrunedApplyVO.getNotRetrunedDate(),"5");
            }

        }
    }


}
